//; ---------------------------------------------------------------------------
//; Object 23 - missile that Buzz	Bomber throws
//; ---------------------------------------------------------------------------

#include "missile.h"
#include "../explosions.h"

#include "../../sprite.h"
#include "../../objectsystemNEWER.h"

static object *obj;

//EXTERN DEFINITIONS HERE
extern word v_limitbtm2;

//; ---------------------------------------------------------------------------
//; Animation script - missile that Buzz Bomber throws
//; ---------------------------------------------------------------------------
byte flare[4]   = {  7, 0, 1, afRoutine };
byte missile[4] = {  1,	2, 3, afEnd };

byte *Ani_Missile[2] = { flare, missile };

//; ---------------------------------------------------------------------------
//; Sprite mappings - missile that Buzz Bomber throws
//; ---------------------------------------------------------------------------
byte Flare1[6] =  {  1,
		  0xF8, 5, 0, 0x24, 0xF8  //; buzz bomber firing flare
};
byte Flare2[6] =  {  1,
		  0xF8, 5, 0, 0x28, 0xF8
};
byte Ball1[6] =   {  1,
		  0xF8, 5, 0, 0x2C, 0xF8  //; missile itself
};
byte Ball2[6] =   {  1,
		  0xF8, 5, 0, 0x33, 0xF8
};

byte *Map_Missile[4] = { Flare1, Flare2, Ball1, Ball2 };
//==========

void (*Msl_Index[5])() = { Msl_Main, Msl_Animate, Msl_FromBuzz, Msl_Delete, Msl_FromNewt };

//OBJECT:					; XREF: Obj_Index
void Missile(object *_obj)
{
    obj = _obj;

    //moveq	#0,d0
    //move.b	obRoutine(a0),d0
    byte routine = obj->Routine/2;

    //move.w	Msl_Index(pc,d0.w),d1
    //jmp	Msl_Index(pc,d1.w)
    (*Msl_Index[routine])();
}

//; ===========================================================================

#define parent 0x3C

//OBJECT_Main:	; Routine 0
void Msl_Main()
{
    //Msl_Main:	; Routine 0
    //subq.w	#1,$32(a0)
    ptrsubobjvariableword(0x32, obj, 1);
 
    //bpl.s	Msl_ChkCancel
    if (ptrgetobjvariableword(0x32, obj) > 0) { Msl_ChkCancel(); }
    else
    {
        //addq.b	#2,obRoutine(a0)
        obj->Routine = obj->Routine + 2;

        //move.l	#Map_Missile,obMap(a0)
        obj->Map = Map_Missile;

	//move.w	#$2444,obGfx(a0)
        obj->Gfx = 0x2444;

	//move.b	#4,obRender(a0)
        obj->Render = 4;

	//move.b	#3,obPriority(a0)
        obj->Priority = 3;

	//move.b	#8,obActWid(a0)
        obj->ActionWidth = 8;

	//andi.b	#3,obStatus(a0)
        obj->Status = obj->Status & 3;

	//tst.b	obSubtype(a0)	; was object created by	a Newtron?
        //beq.s	Msl_Animate	; if not, branch
        if (obj->Subtype == 0) { Msl_Animate(); }
        else
        {		
            //move.b	#8,obRoutine(a0) ; run "Msl_FromNewt" routine
            obj->Routine = 8;

            //move.b	#$87,obColType(a0)
            obj->ColType = 0x87;
 
	    //move.b	#1,obAnim(a0)
            obj->Anim = 1;

	    //bra.s	Msl_Animate2
            Msl_Animate2();
        }
    }
}

//Msl_Animate:	; Routine 2
void Msl_Animate()
{
    //bsr.s	Msl_ChkCancel
    Msl_ChkCancel();

    //lea	(Ani_Missile).l,a1
    byte **aniScript = Ani_Missile;

    //bsr.w	AnimateSprite
    AnimateSprite(obj, aniScript);

    //bra.w	DisplaySprite
    DisplaySprite(obj);
}

//; ---------------------------------------------------------------------------
//; Subroutine to	check if the Buzz Bomber which fired the missile has been
//; destroyed, and if it has, then cancel	the missile
//; ---------------------------------------------------------------------------
//; ||||||||||||||| S U B	R O U T	I N E |||||||||||||||||||||||||||||||||||||||


//Msl_ChkCancel:				; XREF: Msl_Main
void Msl_ChkCancel()
{
    //movea.l	parent(a0),a1
    object *parObj = (object*)ptrgetobjvariablelong(parent, obj);

    //cmpi.b	#id_ExplosionItem,0(a1) ; has Buzz Bomber been destroyed? 
    //beq.s	Msl_Delete	; if yes, branch
    if (obj->ID == id_ExplosionItem)
    {
        Msl_Delete();
    }
    
    //rts	
}   //; End of function Msl_ChkCancel

//; ===========================================================================

//Msl_FromBuzz:	; Routine 4
void Msl_FromBuzz()
{
    //btst	#7,obStatus(a0)
    //bne.s	@explode
    if ((obj->Status & 0x80) == 0)
    {
        //move.b	#$87,obColType(a0)
        obj->ColType = 0x87;

	//move.b	#1,obAnim(a0)
        obj->Anim = 1;

	//bsr.w	SpeedToPos
        SpeedToPos(obj);

	//lea	(Ani_Missile).l,a1
        byte **aniScript = Ani_Missile;

	//bsr.w	AnimateSprite
        AnimateSprite(obj, aniScript);

	//bsr.w	DisplaySprite
        DisplaySprite(obj);

	//move.w	(v_limitbtm2).w,d0
	//addi.w	#$E0,d0
        word lowBound = v_limitbtm2 + 0xE0;

	//cmp.w	obY(a0),d0	; has object moved below the level boundary?
        //bcs.s	Msl_Delete	; if yes, branch
        if (obj->Y > lowBound)
        {
	    Msl_Delete();	
	}	
        //rts	
        //; ===========================================================================
    }
    else
    {
        //@explode:
	//move.b	#id_MissileDissolve,0(a0) ; change object to an explosion (Obj24)
        //obj->ID = id_MissileDissolve;

	//move.b	#0,obRoutine(a0)
        obj->Routine = 0;

	//bra.w	MissileDissolve
        //MissileDissolve();
    }
}   

//; ===========================================================================

//Msl_Delete:	; Routine 6
void Msl_Delete()
{
    //bsr.w	DeleteObject
    DeleteObject(obj);
}
	
//; ===========================================================================

//Msl_FromNewt:	; Routine 8
void Msl_FromNewt()
{
    //tst.b	obRender(a0)
    //bpl.s	Msl_Delete
    if ((signed char)obj->Render > 0)
    {
        Msl_Delete();
    }
    else
    {
	//bsr.w	SpeedToPos
        SpeedToPos(obj);
        
        Msl_Animate2();
    }
}

//Msl_Animate2:				; XREF: Msl_Main
void Msl_Animate2()
{
	//lea	(Ani_Missile).l,a1
        byte **aniScript = Ani_Missile;

	//bsr.w	AnimateSprite
        AnimateSprite(obj, aniScript);

	//bsr.w	DisplaySprite
        DisplaySprite(obj);

        //rts
}
